RFFT

对输入复数序列执行一维快速傅里叶变换(FFT)或逆变换(IFFT)。 内部基于分治 FFT 算法, 并使用预计算旋转因子(twiddle factor)以提升性能。 傅里叶变换,可以对参数进行调整,以实现FFT/IFFT/RFFT/IRFFT。

数学定义如下:

\[X(k) = \sum_{n=0}^{N-1} x(n)\,e^{-j 2\pi kn / N} \quad (\text{Forward FFT})\]
\[x(n) = \sum_{k=0}^{N-1} X(k)\,e^{j 2\pi kn / N} \quad (\text{Inverse FFT})\]

其中 \(N\) 为 FFT 点数。

输入:
  • input - 输入复数数据地址。

  • fft_size - FFT 点数。

  • dir - 变换方向:
    • FFT_FORWARD:正向 FFT

    • FFT_INVERSE:反向 FFT

  • scratch_ptr - 临时缓冲区地址,用于存放旋转因子及中间计算结果。

  • twiddle - 旋转因子地址(仅共享存储版本使用)。

  • fft_size1 - 第一阶段 FFT 点数(仅共享存储版本使用)。

  • fft_size2 - 第二阶段 FFT 点数(仅共享存储版本使用)。

  • core_mask - 核掩码(仅共享存储版本需要)。

输出:
  • output - 输出复数序列地址。

内部核心计算公式如下: 对于FFT,它计算以下表达式:

\[X[\omega_1, \dots, \omega_d] = \sum_{n_1=0}^{N_1-1} \dots \sum_{n_d=0}^{N_d-1} x[n_1, \dots, n_d] e^{-j\ 2 \pi \sum_{i=0}^d \frac{\omega_i n_i}{N_i}},\]

其中, \(d\) = signal_ndim 是信号的维度,\(N_i\) 则是信号第 \(i\) 个维度的大小。

对于IFFT,它计算以下表达式:

\[X[\omega_1, \dots, \omega_d] = \frac{1}{\prod_{i=1}^d N_i} \sum_{n_1=0}^{N_1-1} \dots \sum_{n_d=0}^{N_d-1} x[n_1, \dots, n_d] e^{\ j\ 2 \pi \sum_{i=0}^d \frac{\omega_i n_i}{N_i}},\]

其中, \(d\) = signal_ndim 是信号的维度,\(N_i\) 则是信号第 \(i\) 维的大小。

备注

  • FFT/IFFT要求complex64或complex128类型的输入,返回complex64或complex128类型的输出。

  • RFFT要求bool, uint8, int8, int16, int32, int64, float32或float64类型的输入, 返回complex64或complex128类型的输出。

  • IRFFT要求complex64或complex128类型的输入,返回float32或float64类型的输出。

参数:
  • signal_ndim (int) - 表示每个信号中的维数,控制着傅里叶变换的维数,其值只能为1、2或3。

  • inverse (bool) - 表示该操作是否为逆变换,用以选择FFT 和 RFFT 或 IFFT 和 IRFFT。

    • 如果为 True ,则为IFFT 和 IRFFT。

    • 如果为 False ,FFT 和 RFFT。

  • real (bool) - 表示该操作是否为实变换,与 inverse 共同决定具体的变换模式:

    • inverseFalserealFalse :对应FFT模式。

    • inverseTruerealFalse :对应IFFT模式。

    • inverseFalserealTrue :对应RFFT模式。

    • inverseTruerealTrue :对应IRFFT模式。

  • norm (str,可选) - 表示该操作的规范化方式,可选值:[ "backward" , "forward" , "ortho" ]。默认值: "backward"

    • “backward”,正向变换不缩放,逆变换按 \(1/n\) 缩放,其中 n 表示输入 x 的元素数量。。

    • “ortho”,正向变换与逆变换均按 \(1/\sqrt n\) 缩放。

    • “forward”,正向变换按 \(1/n\) 缩放,逆变换不缩放。

  • onesided (bool,可选) - 控制输入是否减半以避免冗余。默认值: True

  • signal_sizes (tuple,可选) - 原始信号的大小(RFFT变换之前的信号,不包含batch这一维),只有在IRFFT模式下和设置 onesided 为True时需要该参数,需要满足 以下条件。默认值: ()

    • signal_sizes 的长度等于IRFFT的 signal_ndim\(len(signal\_sizes)=signal\_ndim\)

    • signal_sizes 的最后一个维度除以2等于IRFFT输入的最后一个维度: \(signal\_size[-1]/2+1=x.shape[-1]\)

    • 除了最后一个维度外, signal_sizes 的维度与输入shape完全相同: \(signal\_sizes[:-1]=x.shape[:-1]\)

异常:
  • TypeError - 如果FFT/IFFT/IRFF的输入类型不是以下类型之一:complex64、complex128。

  • TypeError - 如果输入的类型不是Tensor。

  • ValueError - 如果输入 x 的维度小于 signal_ndim

  • ValueError - 如果 signal_ndim 大于3或小于1。

  • ValueError - 如果 norm 取值不是”backward”、”forward”或”ortho”。

支持平台:

FT78NE MT7004

类型支持:
  • FT78NE:cplx64cplx128

  • MT7004:cplx64

共享存储版本:

void c64_rfft_s(fftw_complex *input, fftw_complex *output, fftw_complex *scratch_ptr, fftw_complex *twiddle, int fft_size1, int fft_size2, char dir, int core_mask)
void c128_rfft_s(fftw_complex *input, fftw_complex *output, fftw_complex *scratch_ptr, fftw_complex *twiddle, int fft_size1, int fft_size2, char dir, int core_mask)

C 调用示例:

 1// FT78NE 示例(共享存储版本)
 2#include <stdio.h>
 3#include <rfft.h>
 4
 5int main(int argc, char* argv[]) {
 6    fftw_complex *input   = (fftw_complex *)0xA0000000;
 7    fftw_complex *output  = (fftw_complex *)0xC0000000;
 8    fftw_complex *scratch = (fftw_complex *)0xA1000000;
 9    fftw_complex *twiddle = (fftw_complex *)0xA2000000;
10
11    int fft_size1 = 32;
12    int fft_size2 = 32;
13    int core_mask = 0xff;
14
15    c64_rfft_s(input, output, scratch, twiddle,
16               fft_size1, fft_size2, FFT_FORWARD, core_mask);
17    return 0;
18}

私有存储版本:

void c64_rfft_p(fftw_complex *input, fftw_complex *output, fftw_complex *scratch_ptr, int fft_size, char dir)
void c128_rfft_p(fftw_complex *input, fftw_complex *output, fftw_complex *scratch_ptr, int fft_size, char dir)

C 调用示例:

 1// FT78NE 示例(私有存储版本)
 2#include <stdio.h>
 3#include <rfft.h>
 4
 5int main(int argc, char* argv[]) {
 6    fftw_complex *input   = (fftw_complex *)0x10810000;
 7    fftw_complex *output  = (fftw_complex *)0x10820000;
 8    fftw_complex *scratch = (fftw_complex *)0x10830000;
 9
10    int fft_size = 1024;
11
12    c64_rfft_p(input, output, scratch, fft_size, FFT_FORWARD);
13    return 0;
14}